/*
 * @Author: 肖芬芳 10547202+xiao-fenfang@user.noreply.gitee.com
 * @Date: 2022-07-20 08:52:15
 * @LastEditors: 肖芬芳 1911683843@qq.com
 * @LastEditTime: 2022-12-02 11:14:59
 * @FilePath: \vue-api-serverc:\Users\Administrator\Desktop\vite-project\src\util\http\axios.ts
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
import axios, { AxiosInstance, AxiosResponse } from 'axios'

import { ElMessage } from 'element-plus'
import { ResCode } from './code'

// 封装请求对象并导出
export class Request {
  public static axiosInstance: AxiosInstance

  // 初始化：
  public static init () {
    // 创建一个axios实例，并构建基本配置
    this.axiosInstance = axios.create({
      baseURL: 'api',
      timeout: 3000
    })

    // 初始化拦截器
    this.initInterpretors()
    return axios
  }

  // 拦截器封装
  // 拦截器：在请求或响应被 then 或 catch 处理前拦截它们
  // 目的：设置token
  public static initInterpretors () {
    // 设置post请求头
    this.axiosInstance.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded'

    /**
     * 请求拦截器
     * 目的：在每次请求前，如果存在token则在请求头中携带token
     */
    this.axiosInstance.interceptors.request.use(function (config) {
      // 在发送请求之前做些什么
      // config：记录请求的相关信息
      // 如果config.headers具有真值（不是undefined,null,NAN,false,0中的任意一种），则这个a可以被使用。否则将config.headers定义为一个空的object对象{}，防止以后使用报错
      config.headers = config.headers || {}

      // 记录token值
      if (localStorage.getItem('t')) {
        config.headers.Authorization = localStorage.getItem('t') || ''
      }
      return config
    }, function (error) {
      // 对请求错误做些什么
      return Promise.reject(error)
    })

    /*
      响应拦截器
      希望将错误信息直接通过提示出来
    */
    this.axiosInstance.interceptors.response.use(function (res: AxiosResponse) {
      if (res.data.code && res.data.code != 0) {
        // ElMessage.error(ResCode[res.data.code])
        ElMessage.error(res.data.msg)
      }
      return res
    }, function (error) {
      // 对响应错误做点什么
      ElMessage.error('请求失败！')
      return Promise.reject(error)
    })
  }

  // 封装get请求
  public static async get<T, D> (
    url: string,
    params?: D
  ): Promise<AxiosResponse<T, any>> {
    this.init()
    return this.axiosInstance.get<T>(url, params)
  }

  // 封装post请求
  public static post<T, D> (
    url: string,
    data: D
  ): Promise<AxiosResponse<T, any>> {
    this.init()
    return this.axiosInstance.post<T>(url, data)
  }

  // 封装delete请求
  public static delete<T, D> (
    url: string,
    data?: D
  ): Promise<AxiosResponse<T, any>> {
    this.init()
    return this.axiosInstance.delete<T>(url, data)
  }
}
